<template>
    <div class="carouselContainer" ref="container">
        <!-- 翻页容器 -->
        <div
            class="pageWrapper"
            :style="{
                transform: `translateX(${totalOffset}px)`
            }"
            @mousedown="startDrag"
            @mousemove="onDrag"
            @mouseup="endDrag"
            @mouseleave="endDrag"
            @touchstart="startDrag"
            @touchmove="onDrag"
            @touchend="endDrag"
        >
            <div
                v-for="(page, pageIndex) in videoPages"
                :key="`page-${pageIndex}`"
                class="videoPage"
            >
                <div
                    v-for="item in page"
                    :key="`video-${item.id}`"
                    class="video"
                    @click="() => openVideoIfNotDragging(item)"
                >
                    <div class="videoTop">
                        <img class="poster" :src="item.poster" alt="" draggable="false"/>
                        <img
                            class="playVideoBtn"
                            src="/src/assets/img/common/playvideo.webp"
                            alt=""
                            draggable="false"
                        />
                    </div>
                    <div class="videoBottom">
                        <span>{{ item.description }}</span>
                        <img
                            src="/src/assets/img/common/logoYoutube.webp"
                            alt=""
                            draggable="false"
                        />
                    </div>
                </div>
            </div>
        </div>

        <img
            v-show="!isFirstPage"
            class="prePageBtn"
            src="/src/assets/img/common/carouselArrow.webp"
            alt=""
            @click="prePage"
        />
        <img
            v-show="!isLastPage"
            class="nextPageBtn"
            src="/src/assets/img/common/carouselArrow.webp"
            alt=""
            @click="nextPage"
        />

        <div class="dotGroup">
            <span
                v-for="(dot, dotIndex) in totalDots"
                :key="`dot-${dotIndex}`"
                class="dot"
                :class="{ active: dotIndex === currentPage }"
                @click="goToPage(dotIndex)"
            ></span>
        </div>

        <div v-if="showVideo" class="overlay" @click="closeVideo">
            <div class="video-popup" @click.stop>
                <video :src="currentVideoSrc" ref="videoPlayer" preload controls>
                    Your browser does not support the video tag.
                </video>
            </div>
        </div>
    </div>
</template>

<script setup>
import {ref, computed} from 'vue';

const showVideo = ref(false);
const currentVideoSrc = ref('');
const videoPlayer = ref(null);
const currentPage = ref(0);
const container = ref(null);
const dragStartX = ref(0);
const dragDelta = ref(0);
const totalOffset = ref(0);
const isDragging = ref(false);
const dragThreshold = ref(30);
const animationDuration = 300;
const easingFunction = 'cubic-bezier(0.25, 0.46, 0.45, 0.94)';

const {allVideos} = defineProps(['allVideos']);
const videosPerPage = 2;

const videoPages = computed(() => {
    const pages = [];
    for (let i = 0; i < allVideos.length; i += videosPerPage) {
        pages.push(allVideos.slice(i, i + videosPerPage));
    }
    return pages;
});

const totalPages = computed(() => videoPages.value.length);
const totalDots = computed(() => totalPages.value);
const isFirstPage = computed(() => currentPage.value === 0);
const isLastPage = computed(() => currentPage.value === totalPages.value - 1);
const pageWidth = () => container.value?.clientWidth || window.innerWidth;

const openVideo = (src) => {
    currentVideoSrc.value = src;
    showVideo.value = true;
    document.body.style.overflow = 'hidden';
    setTimeout(() => videoPlayer.value?.play(), 100);
};

const closeVideo = () => {
    showVideo.value = false;
    document.body.style.overflow = 'auto';
    videoPlayer.value?.pause();
    videoPlayer.value.currentTime = 0;
};

const startDrag = (e) => {
    // 排除播放按钮区域拖拽
    const target = e.target;
    if (target.closest('.playVideoBtn')) return;

    isDragging.value = true;
    dragStartX.value = e.type.includes('mouse') ? e.clientX : e.touches[0].clientX;
    dragDelta.value = 0;
};

const onDrag = (e) => {
    if (!isDragging.value) return;
    const currentX = e.type.includes('mouse') ? e.clientX : e.touches[0].clientX;
    const delta = currentX - dragStartX.value;
    dragDelta.value = delta;
    totalOffset.value = -currentPage.value * pageWidth() + delta;
};

const endDrag = () => {
    if (!isDragging.value) return;
    isDragging.value = false;
    const delta = dragDelta.value;
    const pageWidthVal = pageWidth();

    if (Math.abs(delta) < dragThreshold.value) {
        smoothScrollTo(pageWidthVal * currentPage.value);
        return;
    }

    const scrollRatio = delta / pageWidthVal;
    let targetPage = currentPage.value;

    if (delta > 0 && !isFirstPage.value) {
        targetPage = scrollRatio > 0.3 ? currentPage.value - 1 : currentPage.value;
    } else if (delta < 0 && !isLastPage.value) {
        targetPage = scrollRatio < -0.3 ? currentPage.value + 1 : currentPage.value;
    } else {
        bounceWithVelocity(delta);
        return;
    }

    smoothScrollTo(pageWidthVal * targetPage);
    currentPage.value = targetPage;
};

const smoothScrollTo = (targetX) => {
    totalOffset.value = -targetX;
};

const bounceWithVelocity = (delta) => {
    const velocity = delta / 100;
    const bounceDistance = Math.min(Math.abs(velocity) * 80, 100);

    totalOffset.value += isFirstPage.value ? bounceDistance : -bounceDistance;

    setTimeout(() => {
        totalOffset.value = -currentPage.value * pageWidth();
    }, 100);
};

const openVideoIfNotDragging = (item) => {
    if (Math.abs(dragDelta.value) < dragThreshold.value && !isDragging.value) {
        openVideo(item.src);
    }
};

const prePage = () => {
    if (isFirstPage.value) {
        bounceWithVelocity(-100);
        return;
    }
    currentPage.value--;
    slideToCurrent();
};

const nextPage = () => {
    if (isLastPage.value) {
        bounceWithVelocity(100);
        return;
    }
    currentPage.value++;
    slideToCurrent();
};

const goToPage = (page) => {
    currentPage.value = page;
    slideToCurrent();
};

const slideToCurrent = () => {
    smoothScrollTo(pageWidth() * currentPage.value);
};
</script>

<style scoped>
.carouselContainer {
    position: relative;
    overflow: hidden;
    margin-bottom: 50px;
}

.pageWrapper {
    display: flex;
    will-change: transform;
    transition: transform 300ms cubic-bezier(0.25, 0.46, 0.45, 0.94);
}

.videoPage {
    flex-shrink: 0;
    width: 100%;
    padding: 50px 3%;
    display: flex;
    justify-content: space-between;
}

.video {
    flex-basis: calc(50% - 20px);
    border-radius: 20px;
    box-shadow: 0 10px 30px rgba(0, 0, 0, 0.25);
    margin-bottom: 40px;
    transition: all 0.3s ease-in-out;
    cursor: pointer;
}

.video:hover {
    transform: scale(1.02);
}

.videoTop {
    position: relative;
}

.videoTop .poster {
    width: 100%;
    border-top-left-radius: 20px;
    border-top-right-radius: 20px;
    user-select: none;
}

.videoTop .playVideoBtn {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    width: 20%;
    user-select: none;
    pointer-events: none;
}

.videoBottom {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 20px;
}

.videoBottom span {
    font-size: 15px;
    color: #2d85f3;
    user-select: none;
}

.videoBottom img {
    width: 20%;
    user-select: none;
    pointer-events: none;
}

.prePageBtn,
.nextPageBtn {
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
    width: 4%;
    cursor: pointer;
    -webkit-user-drag: none;
}

.prePageBtn {
    left: 0;
}

.nextPageBtn {
    right: 0;
    transform: translateY(-50%) rotateY(180deg);
}

.dotGroup {
    position: absolute;
    bottom: 20px;
    left: 50%;
    transform: translateX(-50%);
    display: flex;
    gap: 10px;
}

.dot {
    width: 14px;
    height: 14px;
    border-radius: 50%;
    background-color: #ccc;
    cursor: pointer;
}

.dot.active {
    background-color: #2d85f3;
    width: 24px;
    border-radius: 7px;
    transition: width 0.3s ease-in-out;
}

.overlay {
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background-color: rgba(0, 0, 0, 0.7);
    z-index: 1000;
    display: flex;
    justify-content: center;
    align-items: center;
}

.video-popup {
    z-index: 1001;
    width: 80%;
}

.video-popup video {
    border-radius: 20px;
    width: 100%;
}
</style>